package com.personal.gateway.flinkAllCommand.flinkMetrics;

import com.personal.gateway.custom.customEnum.flinkCommandEnum.FlinkMetricsEnum;
import com.personal.gateway.flinkAllCommand.configurationOption.ConfigurationOption;
import com.personal.gateway.flinkAllCommand.configurationOption.ConfigurationOptionBuilder;
import com.personal.gateway.flinkAllCommand.configurationOption.KeyIndexInfomationDao;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationGenerator.ConfigurationGeneratorEnum;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationGenerator.ConfigurationGeneratorInteger;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationGenerator.ConfigurationGeneratorString;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationType.ConfigurationTypeEnum;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationType.ConfigurationTypeEnumInterface;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationType.ConfigurationTypeInteger;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationType.ConfigurationTypeString;
import com.personal.gateway.flinkAllCommand.configurationOption.parameterCheck.ParameterCheckEnum;
import com.personal.gateway.flinkAllCommand.configurationOption.parameterCheck.ParameterCheckInteger;
import com.personal.gateway.flinkAllCommand.configurationOption.parameterCheck.ParameterCheckString;
import com.personal.gateway.flinkAllCommand.configurationOption.webObjectGenerator.WebObjectGeneratorEnum;
import com.personal.gateway.flinkAllCommand.configurationOption.webObjectGenerator.WebObjectGeneratorInteger;
import com.personal.gateway.flinkAllCommand.configurationOption.webObjectGenerator.WebObjectGeneratorString;

import javax.annotation.Nonnull;

import static com.personal.gateway.flinkAllCommand.FlinkExecuteCommand.METRICS_CONFIG;

/**
 * @author BigHead
 * @date 2022/1/21 9:43
 * @description InfluxdbConfig TODO 只基础增加一些基础公共配置
 */
public class InfluxdbConfig extends FlinkMetricsTypeClass {


    private final ConfigurationOption<Enum<? extends ConfigurationTypeEnumInterface>, ConfigurationTypeEnum> INFLUXDB_SCHEME = ConfigurationOptionBuilder
            .startBuilder(METRICS_CONFIG, new KeyIndexInfomationDao("INFLUXDB_SCHEME", 1))
            .webShowName("Influxdb连接方式")
            .describe("推送数据到Influxdb的方式")
            .necessary(false)
            .typeEnum(InfluxdbSchemeEnum.INFLUXDB_SCHEMA_TYPE_CLASS)
            .webObjectGenerator(WebObjectGeneratorEnum.class)
            .parameterCheck(ParameterCheckEnum.class)
            .configurationGenerator(ConfigurationGeneratorEnum.class)
            .build();

    private final ConfigurationOption<String, ConfigurationTypeString> INFLUXDB_HOST = ConfigurationOptionBuilder
            .startBuilder(METRICS_CONFIG, new KeyIndexInfomationDao("INFLUXDB_HOST", 2))
            .webShowName("连接Host")
            .describe("用作连接Influxdb的地址")
            .typeString()
            .webObjectGenerator(WebObjectGeneratorString.class)
            .parameterCheck(ParameterCheckString.class)
            .configurationGenerator(ConfigurationGeneratorString.class)
            .build();
    private final ConfigurationOption<Integer, ConfigurationTypeInteger> INFLUXDB_PORT = ConfigurationOptionBuilder
            .startBuilder(METRICS_CONFIG, new KeyIndexInfomationDao("INFLUXDB_PORT", 3))
            .webShowName("连接端口")
            .describe("连接端口")
            .typeInteger()
            .setExampleValue(8086)
            .webObjectGenerator(WebObjectGeneratorInteger.class)
            .parameterCheck(ParameterCheckInteger.class)
            .configurationGenerator(ConfigurationGeneratorInteger.class)
            .build();
    private final ConfigurationOption<String, ConfigurationTypeString> INFLUXDB_DB = ConfigurationOptionBuilder
            .startBuilder(METRICS_CONFIG, new KeyIndexInfomationDao("INFLUXDB_DB", 4))
            .webShowName("Db名")
            .describe("Influxdb的数据库名称")
            .typeString()
            .webObjectGenerator(WebObjectGeneratorString.class)
            .parameterCheck(ParameterCheckString.class)
            .configurationGenerator(ConfigurationGeneratorString.class)
            .build();
    private final ConfigurationOption<String, ConfigurationTypeString> INFLUXDB_RETENTION_POLICY = ConfigurationOptionBuilder
            .startBuilder(METRICS_CONFIG, new KeyIndexInfomationDao("INFLUXDB_RETENTION_POLICY", 5))
            .webShowName("过期策略")
            .describe("Influxdb的自动过期策略名")
            .typeString()
            .webObjectGenerator(WebObjectGeneratorString.class)
            .parameterCheck(ParameterCheckString.class)
            .configurationGenerator(ConfigurationGeneratorString.class)
            .build();
    private final ConfigurationOption<Integer, ConfigurationTypeInteger> INFLUXDB_REPORT_INTERVAL = ConfigurationOptionBuilder
            .startBuilder(METRICS_CONFIG, new KeyIndexInfomationDao("INFLUXDB_REPORT_INTERVAL", 6))
            .webShowName("监控规则")
            .describe("监控信息上报到Influxdb的时间间隔，过短会影响正常执行效率")
            .typeInteger()
            .setExampleValue(60)
            .webObjectGenerator(WebObjectGeneratorInteger.class)
            .parameterCheck(ParameterCheckInteger.class)
            .configurationGenerator(ConfigurationGeneratorInteger.class)
            .build();

    private final ConfigurationOption<Enum<? extends ConfigurationTypeEnumInterface>, ConfigurationTypeEnum> INFLUXDB_CONSISTENCY = ConfigurationOptionBuilder
            .startBuilder(METRICS_CONFIG, new KeyIndexInfomationDao("INFLUXDB_CONSISTENCY", 7))
            .webShowName("一致性策略")
            .describe("Influxdb保存数据的一致性策略")
            .necessary(false)
            .typeEnum(InfluxdbConsistencyEnum.INFLUXDB_CONSISTENCY_TYPE_CLASS)
            .webObjectGenerator(WebObjectGeneratorEnum.class)
            .parameterCheck(ParameterCheckEnum.class)
            .configurationGenerator(ConfigurationGeneratorEnum.class)
            .build();

    @Override
    protected FlinkMetricsEnum[] setFlinkTargetEnums() {
        return new FlinkMetricsEnum[]{FlinkMetricsEnum.INFLUXDB};
    }


    public enum InfluxdbSchemeEnum implements ConfigurationTypeEnumInterface {
        /**
         * HTTP连接方式
         */
        HTTP("http"),
        /**
         * https连接方式
         */
        HTTPS("https");

        public static final Class<Enum<? extends ConfigurationTypeEnumInterface>> INFLUXDB_SCHEMA_TYPE_CLASS = (Class<Enum<? extends ConfigurationTypeEnumInterface>>) (Class<?>) InfluxdbSchemeEnum.class;
        private String schemeName;

        InfluxdbSchemeEnum(String schemeName) {
            this.schemeName = schemeName;
        }

        @Override
        public String getShowValue() {
            return name();
        }

        @Override
        public String getSelectValue() {
            return schemeName;
        }

        @Override
        public boolean checkExist(@Nonnull String... values) {
            if (values.length == 1) {
                return schemeName.equals(values[0]);
            }
            return false;
        }

        @Override
        public boolean checkExist(ConfigurationOption<?, ?> configurationOption, @Nonnull String... values) {
            return false;
        }

        @Override
        public boolean checkExampleValue(ConfigurationOption<?, ?> configurationOption) {
            return false;
        }
    }

    public enum InfluxdbConsistencyEnum implements ConfigurationTypeEnumInterface {
        /**
         * 任何一个节点写入成功后，或者接收节点已将数据写入hinted handoff缓存队列后，就会返回成功给客户端。
         */
        ANY("any"),

        /**
         * 任何一个节点写入成功后，立即返回成功给客户端，不包括成功写入hinted handoff缓存队列。
         */
        ONE("one"),

        /**
         * 当大多数节点写入成功后，会返回成功给客户端。此选项仅在副本数大于2时有意义，否则等效于all。
         */
        QUORUM("quorum"),

        /**
         * 仅在所有节点都写入成功后返回成功。
         */
        ALL("all");


        public static final Class<Enum<? extends ConfigurationTypeEnumInterface>> INFLUXDB_CONSISTENCY_TYPE_CLASS = (Class<Enum<? extends ConfigurationTypeEnumInterface>>) (Class<?>) InfluxdbConsistencyEnum.class;
        private final String consistencyName;

        InfluxdbConsistencyEnum(String consistencyName) {
            this.consistencyName = consistencyName;
        }

        @Override
        public String getShowValue() {
            return name();
        }

        @Override
        public String getSelectValue() {
            return consistencyName;
        }

        @Override
        public boolean checkExist(@Nonnull String... values) {
            if (values.length == 1) {
                return consistencyName.equals(values[0]);
            }
            return false;
        }

        @Override
        public boolean checkExist(ConfigurationOption<?, ?> configurationOption, @Nonnull String... values) {
            return false;
        }

        @Override
        public boolean checkExampleValue(ConfigurationOption<?, ?> configurationOption) {
            return false;
        }
    }
}
